#include "stdafx.h"
#include "manage.h"

#include "RegKey.h"
#include "RegKeyValue.h"
#include "RegFormat.h"

#include <list>
typedef std::list<RegKey> RegKeyArray;
typedef RegKeyArray::iterator RegKeyArrayIter;

RegKeyArray keyArray_;
RegKeyArrayIter curIter_;

void AddKey(const RegKey& key)
{
	keyArray_.push_back(key);
	curIter_ = --keyArray_.end();
}

void ShowValue(CString name, DWORD type, const BYTE* data, size_t len)
{
	RegKeyValue keyValue;
	keyValue.SetName(name);

	DWORD dwData;
	CString strData;
	bool isParser = false;
	switch(type)
	{
	case REG_DWORD:
		memcpy(&dwData,data,4);
		keyValue.SetType(RegTextType_DWORD);
		RegFormat::DWORDToValueData(dwData,keyValue);
		isParser = true;
		break;
	case REG_SZ:
		strData.Format(_T("%s"),data);
		keyValue.SetType(RegTextType_String);
		RegFormat::StringToValueData(strData,keyValue);
		isParser = true;
		break;
	case REG_BINARY:
		keyValue.SetType(RegTextType_Binary);
		RegFormat::BinaryToValueData(data,len,keyValue);
		isParser = true;
		break;
	default:
		isParser = false;
		GD_DBG_LOG("%s:%s false",curIter_->ToNameString(),name);
		break;
	}
	//FLY_DEF_LOG("%s",keyValue.ToString());
	if (isParser)
		curIter_->AddValue(keyValue);
}

void ReadKey(CString path)
{
	RegKey key;
	key.SetName(path);
	//FLY_DEF_LOG("%s",key.ToNameString());
	AddKey(key);

	ReadValue(path);

	HKEY hKey;
	DWORD dwDisposition;

	LONG res;
	res =RegCreateKeyEx(HKEY_CURRENT_USER,path.GetBuffer(),0,NULL,0,
		0,NULL,&hKey,&dwDisposition);

	TCHAR keyName[256];
	DWORD keyNameLen = 256;
	int index = 0;
	while (RegEnumKeyEx(hKey, index, keyName, &keyNameLen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
	{
		CString subKey(keyName,keyNameLen);
		ReadKey(path +_T("\\") + subKey);
		++index;
		keyNameLen = 256;
	}
	RegCloseKey(hKey);
}

void ReadValue(CString path)
{
	HKEY hKey;
	DWORD dwDisposition;

	LONG res;
	res =RegCreateKeyEx(HKEY_CURRENT_USER,path.GetBuffer(),0,NULL,0,
		0,NULL,&hKey,&dwDisposition);

	int index = 0;
	TCHAR keyName[256];
	DWORD keyNameLen = 256;
	BYTE keyValue[1024];
	DWORD keyValueLen = 1024;
	DWORD valueType = 0;
	while (RegEnumValue(hKey, index, keyName, &keyNameLen, NULL, &valueType, keyValue, &keyValueLen) == ERROR_SUCCESS)
	{
		ShowValue(keyName,valueType,keyValue,keyValueLen);
		++index;
		keyNameLen = 256;
		keyValueLen = 1024;
	}

	RegCloseKey(hKey);
}

void WriteKey()
{
	for (RegKeyArrayIter iter = keyArray_.begin(); iter != keyArray_.end(); ++iter)
	{
		HKEY   hKey; 
		DWORD  dwDisposition;
		RegCreateKeyEx(HKEY_CURRENT_USER,iter->GetTextName().GetBuffer(),0,NULL,0,
			0,NULL,&hKey,&dwDisposition); 

		for (size_t i=0; i<iter->GetValueSize();++i)
		{
			RegKeyValue keyValue = iter->GetValue(i);
			switch(keyValue.GetType())
			{
			case RegTextType_Binary:
				{
					BYTE buf[4096];
					size_t realLen = 0;
					RegFormat::ValueDataToBinary(keyValue,buf,4096,realLen);
					RegSetValueEx(hKey,keyValue.GetName(),0,REG_BINARY,buf,realLen);
				}	
				break;
			case RegTextType_DWORD:
				{
					DWORD buf;
					RegFormat::ValueDataToDWORD(keyValue,buf);
					RegSetValueEx(hKey,keyValue.GetName(),0,REG_DWORD,(BYTE*)&buf,sizeof(DWORD));
				}
				break;
			case RegTextType_String:
				{
					CString buf;
					RegFormat::ValueDataToString(keyValue,buf);
					RegSetValueEx(hKey,keyValue.GetName(),0,REG_SZ,(BYTE*)buf.GetBuffer(),buf.GetLength()*sizeof(TCHAR));
				}			
				break;
			}
		}

		RegCloseKey(hKey);
	}

}

#define MAX_LEN 4095
#include <fstream>
void ReadIni(CString path)
{
	using namespace std;
	wifstream wfin;
	wfin.open(path,ios::in);
	wchar_t *pFileBuf= new wchar_t[MAX_LEN/2];
	ZeroMemory(pFileBuf,MAX_LEN);

	while(wfin.getline(pFileBuf,MAX_LEN/2))
	{
		CString line;
		line.Format(L"%s",pFileBuf);
		ZeroMemory(pFileBuf,MAX_LEN);

		if (RegFormat::IsKey(line))
		{
			AddKey(RegKey());
			RegFormat::TextToKeyName(line,*curIter_);
			//FLY_DEF_LOG("%s",regKey.ToNameString());
		}
		else if (RegFormat::IsValue(line))
		{
			RegKeyValue regKeyValue;
			RegFormat::TextToValue(line,regKeyValue);
			curIter_->AddValue(regKeyValue);
			//FLY_DEF_LOG("%s",regKeyValue.ToString());
		}
	}
	ShowLog();
}

void WriteIni(CString path)
{
	using namespace std;
	wofstream wfout;
	wfout.open(path,ios::out);

	for (RegKeyArrayIter iter = keyArray_.begin();iter != keyArray_.end();++iter)
	{
		wfout<<iter->ToNameString().GetBuffer()<<_T('\n');
		for (size_t i=0;i<iter->GetValueSize();++i)
		{
			wfout<<iter->GetValue(i).ToString().GetBuffer()<<_T('\n');
		}
	}
}

void ShowLog()
{
	for (RegKeyArrayIter iter = keyArray_.begin();iter != keyArray_.end();++iter)
	{
		iter->ToAllString();
	}
}